package com.kxxnzstdsw.plugins

import com.kxxnzstdsw.exception.can.UnauthorizedException
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
import org.casbin.jcasbin.main.Enforcer
import org.koin.ktor.ext.inject

fun Application.casbinConfig() {
  val e by inject<Enforcer>()
  install(CasbinPlugin) {
    init(e)
  }
}

fun Route.casbin(
  build: Route.() -> Unit
): Route {
  val casbinRoute = createChild(CasbinRouteSelector())
  casbinRoute.build()
  CasbinConfiguration.providers.addAll(casbinRoute.children.map { it.toString() })
  return casbinRoute
}

class CasbinRouteSelector() : RouteSelector() {
  override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation {
    return RouteSelectorEvaluation.Transparent
  }

  override fun toString(): String = ""
}

class CasbinConfiguration {
  lateinit var enforcer: Enforcer
    private set

  fun init(enforcer: Enforcer) {
    this.enforcer = enforcer
//    enforcer.loadModel()
    enforcer.loadPolicy()
    enforcer.savePolicy()
  }

  companion object {
    val providers: MutableSet<String> = mutableSetOf()
  }
}

val CasbinPlugin = createApplicationPlugin(
  name = "CasbinPlugin",
  createConfiguration = ::CasbinConfiguration
) {
  pluginConfig.apply {
    onCall { call ->
      //        casbin  获取请求的api 获取用户信息 获取动作 判断是否有权限
      if (CasbinConfiguration.providers.any {
          call.request.path().contains(it)
        } && !enforcer.enforce(call.user(), call.request.path(), call.request.httpMethod.value)) {
        throw UnauthorizedException()
      }
    }
  }
}
